package org.apache.zookeeper.recipes;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.leader.*;
import org.apache.curator.retry.RetryNTimes;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <h2></h2>
 * description: 依赖于InterProcessMutex，公平，从zk角度，会按照连接到zkServer的顺序分配leadership
 *
 * @author yongjun.ji(yongjun.ji @ ucarinc.com)
 * @since 1.0 2020/6/15 14:35
 */
public class LeaderElectionDemo {
    public static void main(String[] args) throws Exception {
        String path = "/testLeaderElection";
        List<LeaderSelector> leaderSelectors = new ArrayList<>(10);
        List<CuratorFramework> clients = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(3, 100));
            client.start();
            clients.add(client);

            LeaderSelectorListener listener = new LeaderSelectorListenerAdapter() {
                @Override
                public void takeLeadership(CuratorFramework client) throws Exception {
                    // this callback will get called when you are the leader
                    // do whatever leader work you need to and only exit
                    // this method when you want to relinquish leadership

                    // 做leader该做的事，该方法执行结束则会归还领导关系。
                    System.out.println("I am the king of the world");
                    TimeUnit.SECONDS.sleep(5);
                }
            };

            LeaderSelector selector = new LeaderSelector(client, path, listener);
            selector.setId("leaser:" + i);
            selector.autoRequeue();  // not required, but this is behavior that you will probably expect
            leaderSelectors.add(selector);
            selector.start();
        }

        System.in.read();

        for (CuratorFramework client : clients) {
            client.close();
        }

    }
}
